<?php
/**
 * This is Users controller test file. 
 *
 * @copyright     Copyright 2008-2010, LilCake.net
 * @link          http://lilcake.net LilCake.net
 * @package       lil
 * @subpackage    lil.tests.cases.controllers
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */
App::import('Controller', 'Lil.Users');
/**
 * TestUsersController class
 *
 * @package       lil
 * @subpackage    lil.tests.cases.controllers
 */
class TestUsersController extends UsersController {
/**
 * autoRender property
 *
 * @var boolean
 * @access public
 */
	var $autoRender = false;
/**
 * redirectUrl property
 *
 * @var boolean
 * @access public
 */
	var $test_redirectUrl = null;
/**
 * renderedAction property
 *
 * @var boolean
 * @access public
 */
	var $test_renderedAction = null;
/**
 * stopped property
 *
 * @var boolean
 * @access public
 */
	var $test_stopped = null;
/**
 * error404 property
 *
 * @var boolean
 * @access public
 */
	var $test_404 = false;
/**
 * redirect method
 *
 * @access public
 * @return void
 */
	function redirect($url, $status = null, $exit = true) {
		$this->test_redirectUrl = $url;
	}
/**
 * render method
 *
 * @access public
 * @return void
 */
	function render($action = null, $layout = null, $file = null) {
		$this->test_renderedAction = $action;
	}
/**
 * _stop method
 *
 * @access private
 * @return void
 */
	function _stop($status = 0) {
		$this->test_stopped = $status;
	}
/**
 * error404 method
 *
 * @access private
 * @return void
 */
	function error404() {
		$this->test_404 = true;
	}
/**
 * test_reset method
 *
 * This method resets all test variables to default state;
 *
 * @access private
 * @return void
 */
	function test_reset() {
		$this->test_redirectUrl = null;
		$this->test_renderedAction = null;
		$this->test_stopped = null;
		$this->test_404 = false;
	}
}
/**
 * UsersControllerTestCase class
 *
 * @package       lil
 * @subpackage    lil.tests.cases.controllers
 */
class UsersControllerTestCase extends CakeTestCase {
/**
 * fixtures property
 *
 * @var array
 * @access public
 */
	var $fixtures = array(
		'plugin.lil.area', 'plugin.lil.areas_user', 'plugin.lil.user',
	);
/**
 * startCase method
 *
 * @access public
 * @return void
 */
	function startCase() {
	    // overwrite configuration with default values
		require dirname(dirname(dirname(dirname(__FILE__)))) . DS . 'config' . DS . 'core.php';
	}
/**
 * startTest method
 *
 * @access public
 * @return void
 */
	function startTest() {
		$this->Users =& new TestUsersController();
		$this->Users->constructClasses();
		$this->Users->Component->initialize($this->Users);
	}
/**
 * endTest method
 *
 * @access public
 * @return void
 */
	function endTest() {
		$this->Users->Session->destroy();
		unset($this->Users);
		ClassRegistry::flush();
	}
/**
 * testAdminIndex method
 *
 * @access public
 * @return void
 */
	function testAdminIndex() {
		$this->Users->params['controller'] = 'users';
		$this->Users->params['action'] = 'admin_index';
		$this->Users->params['prefix'] = 'admin';
		$this->Users->params['url'] = array('url' => 'admin/lil/users'); // needed for Paginate
		
		$this->Users->setAdminAreaId(1);
		
		$this->Users->beforeFilter();
		$this->Users->Component->startup($this->Users);
		
		$this->Users->admin_index();
		$this->assertTrue(empty($this->Users->User->id));
	}
/**
 * testAdminAdd method
 *
 * @access public
 * @return void
 */
	function testAdminAdd() {
		$this->Users->params['controller'] = 'users';
		$this->Users->params['action'] = 'admin_add';
		$this->Users->params['prefix'] = 'admin';
		$this->Users->params['admin'] = true;
		$this->Users->Session->write('admin.area', array('Area' =>
			array(
				'id'  => 1,
				'name'  => 'My First Area',
				Configure::read('Lil.areaSlugField') => 'first',
				'description' => 'This is my first area.',
				'theme' => null
			)
		));

		$this->Users->beforeFilter();
		$this->Users->Component->startup($this->Users);
		
		////////////////////////////////////////////////////////////////////////////////////////////
		// 1. Check normal add
		////////////////////////////////////////////////////////////////////////////////////////////
		
		$this->Users->data = array(
			'User' => array(
				'admin'    => true,
				'name'     => 'New User From TestSuite',
				'email'    => 'user@testsuite.com',
				'username' => 'testsuite_user',
				'passwd'   => '',
			)
	    );
	    
		$this->Users->admin_add();
		
		//assert that some sort of session flash was set.
		$this->assertTrue($this->Users->Session->check('Message.flash.message'));
		
		$expected_url = Router::normalize($this->Users->test_redirectUrl);
		
		$this->assertEqual(
			Router::normalize(array('admin' => true, 'plugin' => 'lil', 'controller' => 'users', 'action' => 'index')),
			$expected_url
		);

		// a new setting has been added
		$this->assertFalse(empty($this->Users->User->id));
		
		////////////////////////////////////////////////////////////////////////////////////////////
		// 2. Check invalid data
		////////////////////////////////////////////////////////////////////////////////////////////
		$this->Users->test_reset();
		$this->Users->data = array(
			'User' => array(
				'name' => '',
			)
	    );
	    
	    $this->Users->admin_add();
	    $this->assertEqual($this->Users->Session->read('Message.flash.element'), 'error');
	    $this->assertFalse($this->Users->test_404);
	}
/**
 * testAdminEdit method
 *
 * @access public
 * @return void
 */
	function testAdminEdit() {
		$this->Users->params['controller'] = 'users';
		$this->Users->params['action'] = 'admin_edit';
		$this->Users->params['prefix'] = 'admin';
		$this->Users->Session->write('admin.area', array('Area' =>
		array(
			'id'  => 1,
			'name'  => 'My First Area',
			Configure::read('Lil.areaSlugField') => 'first',
			'description' => 'This is my first area.',
			'theme' => null
		)
		));

		$this->Users->beforeFilter();
		$this->Users->Component->startup($this->Users);

		////////////////////////////////////////////////////////////////////////////////////////////
		// 1. Check normal edit
		////////////////////////////////////////////////////////////////////////////////////////////
		
		// check for existing value
		$this->assertEqual('John Doe', $this->Users->User->field('name', array('User.id' => 1)));

		$this->Users->data = array(
			'User' => array(
			    'id'   => 1,
				'name' => 'John Malkovic'
			)
	    );
	    
		$this->Users->admin_edit(1);

		//assert that some sort of session flash was set.
		$this->assertTrue($this->Users->Session->check('Message.flash.message'));

		$expected_url = Router::normalize($this->Users->test_redirectUrl);
		$this->assertEqual(
			Router::normalize(array('admin' => true, 'plugin' => 'lil', 'controller' => 'users', 'action' => 'index')),
			$expected_url
		);

		// a new setting has been added
		$this->assertEqual('John Malkovic', $this->Users->User->field('name', array('User.id' => 1)));
		
		////////////////////////////////////////////////////////////////////////////////////////////
		// 2. Check redirect on invalid user
		////////////////////////////////////////////////////////////////////////////////////////////
		$this->Users->test_reset();
		$this->Users->data = null;
		
		$this->Users->admin_edit(-30);
		$this->assertTrue($this->Users->test_404);


		////////////////////////////////////////////////////////////////////////////////////////////
		// 3. Check invalid data
		////////////////////////////////////////////////////////////////////////////////////////////
		$this->Users->test_reset();
		$this->Users->data = array(
			'User' => array(
			    'id'   => 1,
				'name' => '',
			)
	    );
	    
	    $this->Users->admin_edit(1);
	    
	    $this->assertEqual($this->Users->Session->read('Message.flash.element'), 'error');
	    $this->assertFalse($this->Users->test_404);
	}
/**
 * testAdminDelete method
 *
 * @access public
 * @return void
 */
	function testAdminDelete() {
		$this->Users->params['controller'] = 'users';
		$this->Users->params['action'] = 'admin_delete';
		$this->Users->params['prefix'] = 'admin';
		$this->Users->Session->write('admin.area', array('Area' =>
		array(
			'id'  => 1,
			'name'  => 'My First Area',
			Configure::read('Lil.areaSlugField') => 'first',
			'description' => 'This is my first area.',
			'theme' => null
		)
		));

		$this->Users->beforeFilter();
		$this->Users->Component->startup($this->Users);
		
		////////////////////////////////
		// 1. check normal delete
		$this->assertTrue($this->Users->User->hasAny(array('User.id' => 1)));

		$this->Users->admin_delete(1);

		//assert that some sort of session flash was set.
		$this->assertTrue($this->Users->Session->check('Message.flash.message'));

		// redirect url must not be empty
		$this->assertFalse(empty($this->Users->test_redirectUrl));

		$this->assertFalse($this->Users->User->hasAny(array('User.id' => 1)));
		
		////////////////////////////////
		// 2. try to delete unexisting
		$this->Users->admin_delete(-30);

		$this->assertTrue($this->Users->Session->check('Message.flash.message'));
		$this->assertFalse(empty($this->Users->test_redirectUrl));
		$this->assertTrue($this->Users->test_404);
	}
/**
 * testIsAuthorized method
 *
 * @access public
 * @return void
 */
	function testIsAuthorized() {
		$this->Users->params['controller'] = 'users';
		$this->Users->params['action'] = 'admin_index';

		$this->Users->beforeFilter();
		$this->Users->Component->startup($this->Users);
		
		Configure::write('Lil.allowUsersAnything', true);
		$result = $this->Users->isAuthorized();
		$this->assertTrue($result);
		
		Configure::write('Lil.allowUsersAnything', false);
		$result = $this->Users->isAuthorized();
		$this->assertFalse($result);
		
		// authenticate as user 1
		$this->Users->Auth->login('1');
		$result = $this->Users->isAuthorized();
		$this->assertTrue($result);
		
		// authenticate as user 2 who is not admin
		$this->Users->Auth->login('2');
		$result = $this->Users->isAuthorized();
		$this->assertFalse($result);
		
		$this->Users->params['action'] = 'admin_properties';
		$result = $this->Users->isAuthorized();
		$this->assertTrue($result);
	}
/**
 * testLogin method
 *
 * @access public
 * @return void
 */
	function testLogin() {
		$this->Users->params['controller'] = 'users';
		$this->Users->params['action'] = 'login';

		$this->Users->beforeFilter();
		$this->Users->Component->startup($this->Users);
		
		// test2: call login() normally
		$this->Users->login();
		$user = $this->Users->Auth->user();
		$this->assertTrue(empty($user));
		$user = null;
		
		// test2: call login() with user already logged in
		$this->Users->Auth->login('1');
		$this->Users->login();
		$this->assertFalse(empty($this->Users->test_redirectUrl));
		
		$user = $this->Users->Auth->user();
		$this->assertFalse(empty($user));
		$this->Users->Auth->logout();
		
		$user = $this->Users->Auth->user();
		$this->assertTrue(empty($user));
		
		// test3: test remember_me
		$this->Users->Auth->login('1');
		$this->Users->data = array('User' => array(
			'username'    => 'johndoe',
			'passwd'      => Security::hash('admin', null, true),
			'remember_me' => true
		));
		$this->Users->login();
		
		$this->assertFalse(empty($this->Users->test_redirectUrl));
		$user = $this->Users->Auth->user();
		$this->assertFalse(empty($user));
		$cookie = $this->Users->Cookie->read($this->Users->Auth->sessionKey);
		$this->assertFalse(empty($cookie));
		
		$this->Users->Auth->logout();
		
		// test4: test cookies
		$this->Users->data = null;
		$this->Users->login();
		$user = $this->Users->Auth->user();
		$this->assertFalse(empty($user));
		
		$this->Users->Cookie->delete($this->Users->Auth->sessionKey);
	}
/**
 * testLogout method
 *
 * @access public
 * @return void
 */
	function testLogout() {
		$this->Users->params['controller'] = 'users';
		$this->Users->params['action'] = 'logout';

		$this->Users->beforeFilter();
		$this->Users->Component->startup($this->Users);
		
		$this->Users->logout();
		$this->assertTrue($this->Users->Session->check('Message.flash.message'));
		$this->assertFalse(empty($this->Users->test_redirectUrl));
	}

/**
 * testAdminProperties method
 *
 * @access public
 * @return void
 */
	function testAdminProperties() {
		$this->Users->params['controller'] = 'users';
		$this->Users->params['action'] = 'admin_properties';
		$this->Users->beforeFilter();
		$this->Users->Component->startup($this->Users);
		$this->Users->Auth->login('1');

		$this->Users->test_reset();
		
		$this->Users->data = array('User' => array(
			'id'          => 1,
			'name'        => 'John Doe',
			'email'       => 'john@doe.com',
			'old_pass'    => 'admin',
			'passwd'      => 'newpass',
			'repeat_pass' => 'newpass'
		));
		
		$this->Users->admin_properties();
		
		$this->assertFalse(empty($this->Users->test_redirectUrl));
		
		$data = $this->Users->User->read(null, 1);
		
		$this->assertEqual(Security::hash('newpass', null, true), $data['User']['passwd']);
	}
} 
?>